home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: m.. AfteßÒßÒ8 1998/12/15 20:21:41 lhecking Exp $
- */
-
- /* GNUPLOT - metafont.trm */
-
- /*[
- * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
- /*
- * GNUPLOT -- mf.trm
- *
- * This terminal driver supports:
- * Metafont Plot Commands
- *
- * Written by : Pl Hedne
- * Trondheim, Norway
- * Pal.Hedne@termo.unit.no
- */
-
- /*
- * Improvements and bug fixes by Carsten Steger:
- * - Set default plot size to 5 by 3 inches as in the latex- and eepic-
- * drivers
- * - Fixed some bugs concerning resolution dependent output
- * - Added MF_scale function
- * - Added MF_justify_text function and modified MF_put_text function and
- * put_text macro accordingly
- * - Modified MF_move and MF_vector to make output shorter and modified
- * MF_text accordingly
- * - Added various linetypes by plotting dashed lines; had to modify
- * MF_linetype and MF_vector for this
- * - Added MF_arrow function
- * - All global variables and #define'd names begin with MF_ now
- * As a consequence almost nothing of the original code by Pl Hedne remains
- * but credit goes to him for the ingenious trick of storing the character
- * images into picture variables, without which this driver would have been
- * impossible for me to write.
- *
- * 10/03/95: Converted to new terminal layout by Carsten Steger.
- */
-
- #include "driver.h"
-
- #ifdef TERM_REGISTER
- register_term(mf)
- #endif
-
- #ifdef TERM_PROTO
-
- #define MF_DPI (300)
- /* resolution of printer we expect to use; the value itself is not
- * particularly important... it is here only for compatibility to the
- * LaTeX-driver and to get the spacing right. */
-
- /* 5 inches wide by 3 inches high (default) */
- #define MF_XSIZE 5.0
- #define MF_YSIZE 3.0
- #define MF_XMAX (MF_XSIZE*MF_DPI)
- #define MF_YMAX (MF_YSIZE*MF_DPI)
-
- #define MF_HTIC (5*MF_DPI/72)
- #define MF_VTIC (5*MF_DPI/72)
- #define MF_HCHAR (MF_DPI*53/10/72)
- #define MF_VCHAR (MF_DPI*11/72)
-
- TERM_PUBLIC void MF_init __PROTO((void));
- TERM_PUBLIC void MF_graphics __PROTO((void));
- TERM_PUBLIC void MF_text __PROTO((void));
- TERM_PUBLIC int MF_justify_text __PROTO((enum JUSTIFY mode));
- TERM_PUBLIC int MF_text_angle __PROTO((int ang));
- TERM_PUBLIC void MF_linetype __PROTO((int linetype));
- TERM_PUBLIC void MF_move __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void MF_vector __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void MF_arrow __PROTO((unsigned int sx, unsigned int sy,
- unsigned int ex, unsigned int ey,
- TBOOLEAN head));
- TERM_PUBLIC void MF_put_text __PROTO((unsigned int x, unsigned int y, char *str));
- TERM_PUBLIC void MF_reset __PROTO((void));
-
- #define GOT_MF_PROTO
-
- #endif /* TERM_PROTO */
-
-
- #ifndef TERM_PROTO_ONLY
-
- #ifdef TERM_BODY
-
-
- /* Plot size in inches */
- static double MF_xsize = MF_XSIZE;
- static double MF_ysize = MF_YSIZE;
- static int MF_char_code;
- static int MF_ang;
- static int MF_line_type;
- static enum JUSTIFY MF_justify;
- static double MF_dist_left;
- static int MF_is_solid;
- static int MF_picked_up_pen;
- /*
- * We keep track of where we are with respect to dashed lines by using
- * the next five variables. MF_dash_index indicates which element of
- * MF_lines[..].dashlen should be used. The MF_last.. variables keep
- * track of the position of the pen.
- */
- static int MF_dash_index;
- static unsigned int MF_last_x, MF_last_y;
-
- static struct {
- int solid; /* Is the line solid? */
- float thickness; /* Thickness of pen we are going to use */
- int dashlen[4]; /* Length of individual segments; even: line; odd: gap */
- } MF_lines[10] =
- {
- {
- 1, 1.5, { 0, 0, 0, 0 }
- },
- {
- 0, 1.0, { MF_DPI / 60, MF_DPI / 50, MF_DPI / 60, MF_DPI / 50 }
- },
- {
- 1, 1.5, { 0, 0, 0, 0 }
- },
- {
- 0, 1.5, { MF_DPI / 20, MF_DPI / 30, MF_DPI / 20, MF_DPI / 30 }
- },
- {
- 0, 1.5, { MF_DPI / 30, MF_DPI / 20, MF_DPI / 30, MF_DPI / 20 }
- },
- {
- 0, 1.5, { MF_DPI / 15, MF_DPI / 30, MF_DPI / 60, MF_DPI / 30 }
- },
- {
- 0, 1.5, { MF_DPI / 30, MF_DPI / 50, MF_DPI / 30, MF_DPI / 50 }
- },
- {
- 0, 1.5, { MF_DPI / 20, MF_DPI / 50, MF_DPI / 60, MF_DPI / 30 }
- },
- {
- 0, 1.5, { MF_DPI / 30, MF_DPI / 50, MF_DPI / 30, MF_DPI / 30 }
- },
- {
- 0, 1.5, { MF_DPI / 60, MF_DPI / 50, MF_DPI / 60, MF_DPI / 30 }
- }
- /* dash: line, gap, line, gap */
- };
-
-
-
- TERM_PUBLIC void MF_init()
- {
- MF_char_code = 0;
- MF_ang = 0;
-
- fputs("\
- if unknown cmbase: input cmbase fi\n\n\
- tracingstats:=1;\n\
- picture r[];\n\
- \ndef openit = openwindow currentwindow\n\
- from (0,0) to (400,800) at (-50,500) enddef;\n\
- \nmode_setup;\n", gpoutfile);
-
- fputs("\
- \n%Include next eight lines if you have problems with the mode on your system..\n\
- %proofing:=0;\n\
- %fontmaking:=1;\n\
- %tracingtitles:=0;\n\
- %pixels_per_inch:=300;\n\
- %blacker:=0;\n\
- %fillin:=.2;\n\
- %o_correction:=.6;\n\
- %fix_units;\n", gpoutfile);
-
- /* Next lines must be included if text support is needed (CM base used) */
- fputs("\
- \ndef put_text(expr ts,xstart,ystart,rot,justification) =\n\
- begingroup\n\
- text_width:=0;text_height:=0;\n\
- for ind:=0 step 1 until length(ts)-1:\n\
- dec_num:=ASCII substring (ind,ind+1) of ts;\n\
- if unknown r[dec_num]: dec_num:=32; fi\n\
- if dec_num=32: \n\
- text_width:=text_width+wd[65];\n\
- text_height:=GPMAX(text_height,ht[65]+dp[65]);\n\
- elseif dec_num>=0: \n\
- text_width:=text_width+wd[dec_num];\n\
- text_height:=GPMAX(text_height,ht[dec_num]+dp[dec_num]);\n\
- fi\n\
- endfor\n\
- if rot=90:\n\
- if justification=1: ynext:=ystart;\n\
- elseif justification=2: ynext:=round(ystart-text_width/2);\n\
- else: ynext:=round(ystart-text_width);\n\
- fi\n\
- xnext:=xstart+text_height/2;\n\
- else:\n\
- if justification=1: xnext:=xstart;\n\
- elseif justification=2: xnext:=round(xstart-text_width/2);\n\
- else: xnext:=round(xstart-text_width);\n\
- fi\n\
- ynext:=ystart-text_height/2;\n\
- fi\n\
- for ind:=0 step 1 until length(ts)-1:\n\
- dec_num:=ASCII substring (ind,ind+1) of ts;\n\
- if unknown r[dec_num]: dec_num:=32; fi\n\
- if dec_num=32: \n\
- xnext:=xnext+wd[65]*cosd rot;\n\
- ynext:=ynext+wd[65]*sind rot;\n\
- elseif dec_num>=0: \n\
- currentpicture:=currentpicture+r[dec_num] shifted(xnext,ynext)\n\
- rotatedaround ((xnext,ynext),rot); \n\
- xnext:=xnext+wd[dec_num]*cosd rot;\n\
- ynext:=ynext+wd[dec_num]*sind rot;\n\
- fi\n\
- endfor\n\
- endgroup \n\
- enddef;\n", gpoutfile);
-
- fputs("\
- \ndef endchar =\n\
- r[charcode]:=currentpicture;\n\
- wd[charcode]:=w;ht[charcode]:=h;dp[charcode]:=d;\n\
- message \"Picture of charcode no.\" & decimal charcode;\n\
- endgroup;\n\
- enddef;\n\
- let endchar_ = endchar;\n\
- let generate = relax;\n\
- let roman = relax;\n", gpoutfile);
-
- fputs("\
- input cmr10.mf\n\
- if ligs>1: font_coding_scheme:=\"TeX text\";\n\
- spanish_shriek=oct\"074\"; spanish_query=oct\"076\";\n\
- else: font_coding_scheme:=\n\
- if ligs=0: \"TeX typewriter text\"\n\
- else: \"TeX text without f-ligatures\" fi;\n\
- spanish_shriek=oct\"016\"; spanish_query=oct\"017\"; fi\n\
- font_setup;\n\
- input romanu.mf %Roman uppercase.\n\
- input romanl.mf %Roman lowerrcase.\n\
- input greeku.mf %Greek uppercase.\n\
- input romand.mf %Numerals.\n\
- input romanp.mf %Ampersand, question marks, currency sign.\n\
- input romspl.mf %Lowercase specials (dotless \\i, ligature \\ae, etc.)\n\
- input romspu.mf %Uppercase specials (\\AE, \\OE, \\O)\n\
- input punct.mf %Punctuation symbols.\n\
- \nminus=ASCII\"-\"; cmchar \"Minus sign\";\n\
- beginarithchar(minus); \n\
- pickup rule.nib;\n\
- lft x1=hround 1.5u-eps;\n\
- x2=w-x1; y1=y2=math_axis;\n\
- draw z1--z2; % bar\n\
- labels(1,2); \n\
- endchar;\n", gpoutfile);
-
- fputs("\
- \ncmchar \"Period\";\n\
- numeric dot_diam#; dot_diam#:=if monospace: 5/4 fi\\ dot_size#;\n\
- define_whole_blacker_pixels(dot_diam);\n\
- beginchar(\".\",5u#,dot_diam#,0);\n\
- adjust_fit(0,0); pickup fine.nib;\n\
- pos1(dot_diam,0); pos2(dot_diam,90);\n\
- lft x1l=hround(.5w-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot\n\
- penlabels(1,2);\n\
- endchar;\n", gpoutfile);
-
- fputs("\
- \ndef endchar =\n\
- % Next line should probably be removed if CM base is used\n\
- l:=0; r:=w;\n\
- %Include the next two lines if you want to\n\
- %rotate the picture 90 deg.(Portrait to Landscape)\n\
- %currentpicture:=currentpicture rotated 90 shifted (h,0);\n\
- %tmp:=charht; charht:=charwd; charwd:=tmp;\n\
- scantokens extra_endchar;\n\
- if proofing>0: makebox(proofrule); fi\n\
- chardx:=w;\n\
- shipit;\n\
- if displaying>0: makebox(screenrule); showit; fi\n\
- endgroup \n\
- enddef;\n\
- let endchar_ = endchar;\n\
- let generate = input;\n\
- let roman = roman;\n", gpoutfile);
-
- /* font_size must be bigger than em#/16 by METAFONT rules.
- * Therefore make it pretty big so big figures will be
- * handled correctly. Setting font_size to 72pt# lets us
- * handle characters up to 15.94 by 15.94 inches. */
- fputs("\
- \n\nfont_identifier:=\"GNUPLOT\";\n\
- font_size 72pt#;\n\
- th#=0.4pt#; define_whole_pixels(th);\n\
- \npath arrowhead;\n\
- arrowhead = (-7pt,-2pt){dir30}..(-6pt,0pt)..\
- {dir150}(-7pt,2pt) &\n\
- (-7pt,2pt)--(0pt,0pt)--(-7pt,-2pt) & cycle;\n", gpoutfile);
- }
-
-
- TERM_PUBLIC void MF_graphics()
- {
- register struct termentry *t = term;
-
- fprintf(gpoutfile, "\n\nbeginchar(%d,%gin#,%gin#,0);\n",
- MF_char_code, MF_xsize, MF_ysize);
- MF_char_code++;
- fprintf(gpoutfile, "a:=w/%d;b:=h/%d;\n", t->xmax, t->ymax);
- MF_picked_up_pen = 0;
- }
-
-
- TERM_PUBLIC void MF_text()
- {
- fputs("endchar;\n", gpoutfile);
- }
-
-
- TERM_PUBLIC int MF_justify_text(mode)
- enum JUSTIFY mode;
- {
- MF_justify = mode;
- return TRUE;
- }
-
-
- TERM_PUBLIC int MF_text_angle(ang)
- int ang;
- {
- if (ang > 0)
- MF_ang = 90;
- else
- MF_ang = 0;
- return TRUE;
- }
-
-
- TERM_PUBLIC void MF_linetype(linetype)
- int linetype;
- {
- if (linetype >= 8)
- linetype %= 8;
- linetype += 2;
- /* Only output change in pens if it actually affects the pen used */
- if ((MF_lines[linetype].thickness != MF_lines[MF_line_type].thickness) ||
- (!MF_picked_up_pen)) {
- fprintf(gpoutfile, "pickup pencircle scaled %gth;\n",
- MF_lines[linetype].thickness);
- MF_picked_up_pen = 1;
- }
- MF_line_type = linetype;
- MF_dash_index = 0;
- MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
- MF_is_solid = MF_lines[MF_line_type].solid;
- }
-
-
- TERM_PUBLIC void MF_move(x, y)
- unsigned int x, y;
- {
- MF_last_x = x;
- MF_last_y = y;
- MF_dash_index = 0;
- MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
- }
-
-
- TERM_PUBLIC void MF_vector(x, y)
- unsigned int x, y;
- {
- if (MF_is_solid) {
- if (x == MF_last_x && y == MF_last_y)
- fprintf(gpoutfile, "drawdot (%da,%db);\n", x, y);
- else
- fprintf(gpoutfile, "draw (%da,%db)--(%da,%db);\n",
- MF_last_x, MF_last_y, x, y);
- } else {
- double dist_to_go, delta_x, delta_y, inc_x, inc_y;
- double last_x_d, last_y_d, next_x_d, next_y_d;
- unsigned int next_x, next_y;
-
- if (x == MF_last_x && y == MF_last_y) {
- if (!(MF_dash_index & 1))
- fprintf(gpoutfile, "drawdot (%da,%db);\n", x, y);
- } else {
- last_x_d = MF_last_x;
- last_y_d = MF_last_y;
- delta_x = x - last_x_d;
- delta_y = y - last_y_d;
- dist_to_go = sqrt(delta_x * delta_x + delta_y * delta_y);
- inc_x = delta_x / dist_to_go;
- inc_y = delta_y / dist_to_go;
- while (MF_dist_left < dist_to_go) {
- next_x_d = last_x_d + inc_x * MF_dist_left;
- next_y_d = last_y_d + inc_y * MF_dist_left;
- next_x = floor(next_x_d + 0.5);
- next_y = floor(next_y_d + 0.5);
- /* MF_dash_index & 1 == 0 means: draw a line; otherwise just move */
- if (!(MF_dash_index & 1))
- fprintf(gpoutfile, "draw (%da,%db)--(%da,%db);\n",
- MF_last_x, MF_last_y, next_x, next_y);
- MF_last_x = next_x;
- MF_last_y = next_y;
- last_x_d = next_x_d;
- last_y_d = next_y_d;
- dist_to_go -= MF_dist_left;
- MF_dash_index = (MF_dash_index + 1) & 3;
- MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
- }
- delta_x = x - last_x_d;
- delta_y = y - last_y_d;
- MF_dist_left -= sqrt(delta_x * delta_x + delta_y * delta_y);
- if (!(MF_dash_index & 1)) {
- if (x == MF_last_x && y == MF_last_y)
- fprintf(gpoutfile, "drawdot (%da,%db);\n", x, y);
- else
- fprintf(gpoutfile, "draw (%da,%db)--(%da,%db);\n",
- MF_last_x, MF_last_y, x, y);
- }
- }
- }
- MF_last_x = x;
- MF_last_y = y;
- }
-
-
- TERM_PUBLIC void MF_arrow(sx, sy, ex, ey, head)
- unsigned int sx, sy, ex, ey;
- TBOOLEAN head;
- {
- int delta_x, delta_y;
-
- MF_move(sx, sy);
- MF_vector(ex, ey);
- if (head) {
- delta_x = ex - sx;
- delta_y = ey - sy;
- fprintf(gpoutfile, "fill arrowhead rotated angle(%d,%d) shifted (%da,%db);\n",
- delta_x, delta_y, ex, ey);
- }
- }
-
-
- TERM_PUBLIC void MF_put_text(x, y, str)
- unsigned int x, y;
- char *str;
- {
- int i, j = 0;
-
- for (i = 0; i < strlen(str); i++)
- if (str[i] == '"')
- str[i] = '\''; /* Replace " with ' */
- switch (MF_justify) {
- case LEFT:
- j = 1;
- break;
- case CENTRE:
- j = 2;
- break;
- case RIGHT:
- j = 3;
- break;
- }
- fprintf(gpoutfile, "put_text(\"%s\",%da,%db,%d,%d);\n",
- str, x, y, MF_ang, j);
- }
-
-
- TERM_PUBLIC void MF_reset()
- {
- fputs("end.\n", gpoutfile);
- }
-
-
- #endif /* TERM_BODY */
-
- #ifdef TERM_TABLE
-
- TERM_TABLE_START(mf_driver)
- "mf", "Metafont plotting standard",
- MF_XMAX, MF_YMAX, MF_VCHAR, MF_HCHAR,
- MF_VTIC, MF_HTIC, options_null, MF_init, MF_reset,
- MF_text, null_scale, MF_graphics, MF_move, MF_vector,
- MF_linetype, MF_put_text, MF_text_angle,
- MF_justify_text, line_and_point, MF_arrow, set_font_null
- TERM_TABLE_END(mf_driver)
-
- #undef LAST_TERM
- #define LAST_TERM mf_driver
-
- #endif /* TERM_TABLE */
- #endif /* TERM_PROTO_ONLY */
-
-
- #ifdef TERM_HELP
- START_HELP(mf)
- "1 mf",
- "?commands set terminal mf",
- "?set terminal mf",
- "?set term mf",
- "?terminal mf",
- "?term mf",
- "?mf",
- "?metafont",
- " The `mf` terminal driver creates a input file to the METAFONT program. Thus a",
- " figure may be used in the TeX document in the same way as is a character.",
- "",
- " To use a picture in a document, the METAFONT program must be run with the",
- " output file from `gnuplot` as input. Thus, the user needs a basic knowledge",
- " of the font creating process and the procedure for including a new font in a",
- " document. However, if the METAFONT program is set up properly at the local",
- " site, an unexperienced user could perform the operation without much trouble.",
- "",
- " The text support is based on a METAFONT character set. Currently the",
- " Computer Modern Roman font set is input, but the user is in principal free to",
- " chose whatever fonts he or she needs. The METAFONT source files for the",
- " chosen font must be available. Each character is stored in a separate",
- " picture variable in METAFONT. These variables may be manipulated (rotated,",
- " scaled etc.) when characters are needed. The drawback is the interpretation",
- " time in the METAFONT program. On some machines (i.e. PC) the limited amount",
- " of memory available may also cause problems if too many pictures are stored.",
- "",
- " The `mf` terminal has no options.",
- "2 METAFONT Instructions",
- "?commands set terminal mf detailed",
- "?set terminal mf detailed",
- "?set term mf detailed",
- "?mf detailed",
- "?metafont detailed",
- "",
- " - Set your terminal to METAFONT:",
- " set terminal mf",
- " - Select an output-file, e.g.:",
- " set output \"myfigures.mf\"",
- " - Create your pictures. Each picture will generate a separate character. Its",
- " default size will be 5*3 inches. You can change the size by saying `set size",
- " 0.5,0.5` or whatever fraction of the default size you want to have.",
- "",
- " - Quit `gnuplot`.",
- "",
- " - Generate a TFM and GF file by running METAFONT on the output of `gnuplot`.",
- " Since the picture is quite large (5*3 in), you will have to use a version of",
- " METAFONT that has a value of at least 150000 for memmax. On Unix systems",
- " these are conventionally installed under the name bigmf. For the following",
- " assume that the command virmf stands for a big version of METAFONT. For",
- " example:",
- "",
- " - Invoke METAFONT:",
- " virmf '&plain'",
- " - Select the output device: At the METAFONT prompt ('*') type:",
- " \\mode:=CanonCX; % or whatever printer you use",
- " - Optionally select a magnification:",
- " mag:=1; % or whatever you wish",
- " - Input the `gnuplot`-file:",
- " input myfigures.mf",
- " On a typical Unix machine there will usually be a script called \"mf\" that",
- " executes virmf '&plain', so you probably can substitute mf for virmf &plain.",
- " This will generate two files: mfput.tfm and mfput.$$$gf (where $$$ indicates",
- " the resolution of your device). The above can be conveniently achieved by",
- " typing everything on the command line, e.g.:",
- " virmf '&plain' '\\mode:=CanonCX; mag:=1; input myfigures.mf'",
- " In this case the output files will be named myfigures.tfm and",
- " myfigures.300gf.",
- "",
- " - Generate a PK file from the GF file using gftopk:",
- " gftopk myfigures.300gf myfigures.300pk",
- " The name of the output file for gftopk depends on the DVI driver you use.",
- " Ask your local TeX administrator about the naming conventions. Next, either",
- " install the TFM and PK files in the appropriate directories, or set your",
- " environment variables properly. Usually this involves setting TEXFONTS to",
- " include the current directory and doing the same thing for the environment",
- " variable that your DVI driver uses (no standard name here...). This step is",
- " necessary so that TeX will find the font metric file and your DVI driver will",
- " find the PK file.",
- "",
- " - To include your pictures in your document you have to tell TeX the font:",
- " \\font\\gnufigs=myfigures",
- " Each picture you made is stored in a single character. The first picture is",
- " character 0, the second is character 1, and so on... After doing the above",
- " step, you can use the pictures just like any other characters. Therefore, to",
- " place pictures 1 and 2 centered in your document, all you have to do is:",
- " \\centerline{\\gnufigs\\char0}",
- " \\centerline{\\gnufigs\\char1}",
- " in plain TeX. For LaTeX you can, of course, use the picture environment and",
- " place the picture wherever you wish by using the \\makebox and \\put macros.",
- "",
- " This conversion saves you a lot of time once you have generated the font;",
- " TeX handles the pictures as characters and uses minimal time to place them,",
- " and the documents you make change more often than the pictures do. It also",
- " saves a lot of TeX memory. One last advantage of using the METAFONT driver",
- " is that the DVI file really remains device independent, because no \\special",
- " commands are used as in the eepic and tpic drivers."
- END_HELP(mf)
- #endif /* TERM_HELP */
-